#include "../../include/datatype/NcMap.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 哈希表默认大小和负载因子
#define NCMAP_INITIAL_CAPACITY  16
#define NCMAP_MAX_LOAD_FACTOR   0.75
#define NCMAP_RESIZE_FACTOR     2

// NcMap内部数据结构
typedef enum {
    NCMAP_VALUE_INT,      // 整数类型
    NCMAP_VALUE_DOUBLE,   // 小数类型
    NCMAP_VALUE_STRING    // 文本类型
} NcMapValueType;

typedef struct NcMapEntry {
    char* key;                    // 键（字符串）
    NcMapValueType type;          // 值的类型
    union {
        int int_value;            // 整数值
        double double_value;      // 小数值
        char* string_value;       // 文本值
    } value;
    struct NcMapEntry* next;      // 冲突链表的下一个节点
} NcMapEntry;

typedef struct {
    NcMapEntry** buckets;         // 哈希桶数组
    int capacity;                 // 桶的数量
    int size;                     // 元素数量
    char* keys_cache;             // 键列表缓存
} NcMapStruct;

// 字符串哈希函数（DJB2算法）
static unsigned int ncmap_hash(const char* key) {
    if (!key) return 0;
    
    unsigned int hash = 5381;
    int c;
    while ((c = *key++)) {
        hash = ((hash << 5) + hash) + c; // hash * 33 + c
    }
    return hash;
}

// 辅助函数：在指定桶中查找条目
static NcMapEntry* ncmap_find_entry(NcMapEntry* head, const char* key) {
    NcMapEntry* current = head;
    while (current) {
        if (strcmp(current->key, key) == 0) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

// 辅助函数：创建新条目
static NcMapEntry* ncmap_create_entry(const char* key) {
    if (!key) return NULL;
    
    NcMapEntry* entry = (NcMapEntry*)malloc(sizeof(NcMapEntry));
    if (!entry) return NULL;
    
    // 复制键
    size_t key_len = strlen(key);
    entry->key = (char*)malloc(key_len + 1);
    if (!entry->key) {
        free(entry);
        return NULL;
    }
    strcpy(entry->key, key);
    
    entry->next = NULL;
    return entry;
}

// 辅助函数：释放条目
static void ncmap_free_entry(NcMapEntry* entry) {
    if (!entry) return;
    
    free(entry->key);
    if (entry->type == NCMAP_VALUE_STRING && entry->value.string_value) {
        free(entry->value.string_value);
    }
    free(entry);
}

// 辅助函数：调整哈希表大小
static int ncmap_resize(NcMapStruct* map, int new_capacity) {
    if (!map || new_capacity <= 0) return 0;
    
    // 保存旧的桶数组
    NcMapEntry** old_buckets = map->buckets;
    int old_capacity = map->capacity;
    
    // 创建新的桶数组
    map->buckets = (NcMapEntry**)calloc(new_capacity, sizeof(NcMapEntry*));
    if (!map->buckets) {
        map->buckets = old_buckets; // 恢复
        return 0;
    }
    
    map->capacity = new_capacity;
    map->size = 0; // 重新计数
    
    // 重新哈希所有条目
    for (int i = 0; i < old_capacity; i++) {
        NcMapEntry* current = old_buckets[i];
        while (current) {
            NcMapEntry* next = current->next;
            
            // 计算新的桶索引
            unsigned int hash = ncmap_hash(current->key);
            int bucket_index = hash % new_capacity;
            
            // 插入到新桶中
            current->next = map->buckets[bucket_index];
            map->buckets[bucket_index] = current;
            map->size++;
            
            current = next;
        }
    }
    
    // 释放旧桶数组
    free(old_buckets);
    return 1;
}

// 辅助函数：检查是否需要扩容
static void ncmap_check_resize(NcMapStruct* map) {
    if (!map) return;
    
    double load_factor = (double)map->size / map->capacity;
    if (load_factor > NCMAP_MAX_LOAD_FACTOR) {
        ncmap_resize(map, map->capacity * NCMAP_RESIZE_FACTOR);
    }
}

// 创建NcMap实例
__declspec(dllexport) NcMapHandle __stdcall NcMapCreate(void) {
    NcMapStruct* map = (NcMapStruct*)malloc(sizeof(NcMapStruct));
    if (!map) return NULL;
    
    map->buckets = (NcMapEntry**)calloc(NCMAP_INITIAL_CAPACITY, sizeof(NcMapEntry*));
    if (!map->buckets) {
        free(map);
        return NULL;
    }
    
    map->capacity = NCMAP_INITIAL_CAPACITY;
    map->size = 0;
    map->keys_cache = NULL;
    
    return (NcMapHandle)map;
}

// 销毁NcMap实例
__declspec(dllexport) void __stdcall NcMapDestroy(NcMapHandle map) {
    if (!map) return;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    // 释放所有桶中的条目
    for (int i = 0; i < ncmap->capacity; i++) {
        NcMapEntry* current = ncmap->buckets[i];
        while (current) {
            NcMapEntry* next = current->next;
            ncmap_free_entry(current);
            current = next;
        }
    }
    
    // 释放桶数组
    free(ncmap->buckets);
    
    // 释放键缓存
    if (ncmap->keys_cache) {
        free(ncmap->keys_cache);
    }
    
    free(ncmap);
}

// 设置整数值
__declspec(dllexport) int __stdcall NcMapSetInt(NcMapHandle map, const char* key, int value) {
    if (!map || !key) return 0;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    // 计算哈希和桶索引
    unsigned int hash = ncmap_hash(key);
    int bucket_index = hash % ncmap->capacity;
    
    // 查找是否已存在
    NcMapEntry* entry = ncmap_find_entry(ncmap->buckets[bucket_index], key);
    
    if (entry) {
        // 更新现有条目
        if (entry->type == NCMAP_VALUE_STRING && entry->value.string_value) {
            free(entry->value.string_value);
        }
        entry->type = NCMAP_VALUE_INT;
        entry->value.int_value = value;
    } else {
        // 创建新条目
        entry = ncmap_create_entry(key);
        if (!entry) return 0;
        
        entry->type = NCMAP_VALUE_INT;
        entry->value.int_value = value;
        
        // 插入到桶头部
        entry->next = ncmap->buckets[bucket_index];
        ncmap->buckets[bucket_index] = entry;
        ncmap->size++;
        
        // 检查是否需要扩容
        ncmap_check_resize(ncmap);
    }
    
    // 清除键缓存
    if (ncmap->keys_cache) {
        free(ncmap->keys_cache);
        ncmap->keys_cache = NULL;
    }
    
    return 1;
}

// 设置小数值（使用指针传递解决堆栈问题）
__declspec(dllexport) int __stdcall NcMapSetDouble(NcMapHandle map, const char* key, double* value) {
    if (!map || !key || !value) return 0;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    // 计算哈希和桶索引
    unsigned int hash = ncmap_hash(key);
    int bucket_index = hash % ncmap->capacity;
    
    // 查找是否已存在
    NcMapEntry* entry = ncmap_find_entry(ncmap->buckets[bucket_index], key);
    
    if (entry) {
        // 更新现有条目
        if (entry->type == NCMAP_VALUE_STRING && entry->value.string_value) {
            free(entry->value.string_value);
        }
        entry->type = NCMAP_VALUE_DOUBLE;
        entry->value.double_value = *value; // 从指针读取值
    } else {
        // 创建新条目
        entry = ncmap_create_entry(key);
        if (!entry) return 0;
        
        entry->type = NCMAP_VALUE_DOUBLE;
        entry->value.double_value = *value; // 从指针读取值
        
        // 插入到桶头部
        entry->next = ncmap->buckets[bucket_index];
        ncmap->buckets[bucket_index] = entry;
        ncmap->size++;
        
        // 检查是否需要扩容
        ncmap_check_resize(ncmap);
    }
    
    // 清除键缓存
    if (ncmap->keys_cache) {
        free(ncmap->keys_cache);
        ncmap->keys_cache = NULL;
    }
    
    return 1;
}

// 设置字符串值
__declspec(dllexport) int __stdcall NcMapSetString(NcMapHandle map, const char* key, const char* value) {
    if (!map || !key || !value) return 0;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    // 计算哈希和桶索引
    unsigned int hash = ncmap_hash(key);
    int bucket_index = hash % ncmap->capacity;
    
    // 查找是否已存在
    NcMapEntry* entry = ncmap_find_entry(ncmap->buckets[bucket_index], key);
    
    if (entry) {
        // 更新现有条目
        if (entry->type == NCMAP_VALUE_STRING && entry->value.string_value) {
            free(entry->value.string_value);
        }
        
        // 复制新字符串
        size_t value_len = strlen(value);
        entry->value.string_value = (char*)malloc(value_len + 1);
        if (!entry->value.string_value) return 0;
        strcpy(entry->value.string_value, value);
        entry->type = NCMAP_VALUE_STRING;
    } else {
        // 创建新条目
        entry = ncmap_create_entry(key);
        if (!entry) return 0;
        
        // 复制字符串值
        size_t value_len = strlen(value);
        entry->value.string_value = (char*)malloc(value_len + 1);
        if (!entry->value.string_value) {
            ncmap_free_entry(entry);
            return 0;
        }
        strcpy(entry->value.string_value, value);
        entry->type = NCMAP_VALUE_STRING;
        
        // 插入到桶头部
        entry->next = ncmap->buckets[bucket_index];
        ncmap->buckets[bucket_index] = entry;
        ncmap->size++;
        
        // 检查是否需要扩容
        ncmap_check_resize(ncmap);
    }
    
    // 清除键缓存
    if (ncmap->keys_cache) {
        free(ncmap->keys_cache);
        ncmap->keys_cache = NULL;
    }
    
    return 1;
}

// 获取整数值
__declspec(dllexport) int __stdcall NcMapGetInt(NcMapHandle map, const char* key, int* result) {
    if (!map || !key || !result) return 0;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    // 计算哈希和桶索引
    unsigned int hash = ncmap_hash(key);
    int bucket_index = hash % ncmap->capacity;
    
    // 查找条目
    NcMapEntry* entry = ncmap_find_entry(ncmap->buckets[bucket_index], key);
    
    if (entry && entry->type == NCMAP_VALUE_INT) {
        *result = entry->value.int_value;
        return 1;
    }
    
    return 0;
}

// 获取小数值（使用指针传递解决堆栈问题）
__declspec(dllexport) int __stdcall NcMapGetDouble(NcMapHandle map, const char* key, double* result) {
    if (!map || !key || !result) return 0;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    // 计算哈希和桶索引
    unsigned int hash = ncmap_hash(key);
    int bucket_index = hash % ncmap->capacity;
    
    // 查找条目
    NcMapEntry* entry = ncmap_find_entry(ncmap->buckets[bucket_index], key);
    
    if (entry && entry->type == NCMAP_VALUE_DOUBLE) {
        *result = entry->value.double_value; // 写入指针指向的位置
        return 1;
    }
    
    return 0;
}

// 获取字符串值
__declspec(dllexport) const char* __stdcall NcMapGetString(NcMapHandle map, const char* key) {
    if (!map || !key) return NULL;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    // 计算哈希和桶索引
    unsigned int hash = ncmap_hash(key);
    int bucket_index = hash % ncmap->capacity;
    
    // 查找条目
    NcMapEntry* entry = ncmap_find_entry(ncmap->buckets[bucket_index], key);
    
    if (entry && entry->type == NCMAP_VALUE_STRING) {
        return entry->value.string_value;
    }
    
    return NULL;
}

// 删除键值对
__declspec(dllexport) int __stdcall NcMapRemove(NcMapHandle map, const char* key) {
    if (!map || !key) return 0;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    // 计算哈希和桶索引
    unsigned int hash = ncmap_hash(key);
    int bucket_index = hash % ncmap->capacity;
    
    NcMapEntry* current = ncmap->buckets[bucket_index];
    NcMapEntry* prev = NULL;
    
    while (current) {
        if (strcmp(current->key, key) == 0) {
            // 找到要删除的条目
            if (prev) {
                prev->next = current->next;
            } else {
                ncmap->buckets[bucket_index] = current->next;
            }
            
            ncmap_free_entry(current);
            ncmap->size--;
            
            // 清除键缓存
            if (ncmap->keys_cache) {
                free(ncmap->keys_cache);
                ncmap->keys_cache = NULL;
            }
            
            return 1;
        }
        prev = current;
        current = current->next;
    }
    
    return 0;
}

// 获取元素数量
__declspec(dllexport) int __stdcall NcMapSize(NcMapHandle map) {
    if (!map) return 0;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    return ncmap->size;
}

// 检查键是否存在
__declspec(dllexport) int __stdcall NcMapContains(NcMapHandle map, const char* key) {
    if (!map || !key) return 0;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    // 计算哈希和桶索引
    unsigned int hash = ncmap_hash(key);
    int bucket_index = hash % ncmap->capacity;
    
    // 查找条目
    NcMapEntry* entry = ncmap_find_entry(ncmap->buckets[bucket_index], key);
    
    return (entry != NULL) ? 1 : 0;
}

// 清空所有键值对
__declspec(dllexport) void __stdcall NcMapClear(NcMapHandle map) {
    if (!map) return;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    // 释放所有桶中的条目
    for (int i = 0; i < ncmap->capacity; i++) {
        NcMapEntry* current = ncmap->buckets[i];
        while (current) {
            NcMapEntry* next = current->next;
            ncmap_free_entry(current);
            current = next;
        }
        ncmap->buckets[i] = NULL;
    }
    
    ncmap->size = 0;
    
    // 清除键缓存
    if (ncmap->keys_cache) {
        free(ncmap->keys_cache);
        ncmap->keys_cache = NULL;
    }
}

// 获取所有键的列表（分号分隔）
__declspec(dllexport) const char* __stdcall NcMapGetKeys(NcMapHandle map) {
    if (!map) return NULL;
    
    NcMapStruct* ncmap = (NcMapStruct*)map;
    
    if (ncmap->size == 0) return "";
    
    // 如果缓存存在且有效，直接返回
    if (ncmap->keys_cache) {
        return ncmap->keys_cache;
    }
    
    // 计算所需缓存大小
    size_t total_length = 0;
    for (int i = 0; i < ncmap->capacity; i++) {
        NcMapEntry* current = ncmap->buckets[i];
        while (current) {
            total_length += strlen(current->key) + 1; // +1 for separator
            current = current->next;
        }
    }
    
    if (total_length == 0) return "";
    
    // 分配缓存内存
    ncmap->keys_cache = (char*)malloc(total_length);
    if (!ncmap->keys_cache) return NULL;
    
    // 构建键列表
    ncmap->keys_cache[0] = '\0';
    int first = 1;
    
    for (int i = 0; i < ncmap->capacity; i++) {
        NcMapEntry* current = ncmap->buckets[i];
        while (current) {
            if (!first) {
                strcat(ncmap->keys_cache, ";");
            }
            strcat(ncmap->keys_cache, current->key);
            first = 0;
            current = current->next;
        }
    }
    
    return ncmap->keys_cache;
} 